import 'dart:math';

import 'package:flutter/material.dart';

class PaintUtil {
  /// 中心缩放算法
  static Offset centerZoomAlgorithm({
    required Offset center,
    required Offset curCanvasOffset,
    required double curCanvasScale,
    required double preCanvasScale,
  }) {
    double thisTimeCanvasOffsetX = -(center.dx - curCanvasOffset.dx) *
        (curCanvasScale - preCanvasScale) /
        preCanvasScale;
    double thisTimeCanvasOffsetY = -(center.dy - curCanvasOffset.dy) *
        (curCanvasScale - preCanvasScale) /
        preCanvasScale;
    Offset thisTimeCanvasOffset =
        Offset(thisTimeCanvasOffsetX, thisTimeCanvasOffsetY);
    return thisTimeCanvasOffset;
  }

  /// 获取边界点
  static (List<Offset>, Map<String, double>, Rect) getBoundData(
      List<Offset> points) {
    double left = double.infinity;
    double right = double.negativeInfinity;
    double top = double.infinity;
    double bottom = double.negativeInfinity;

    for (var point in points) {
      left = min(point.dx, left);
      right = max(point.dx, right);
      top = min(point.dy, top);
      bottom = max(point.dy, bottom);
    }
    return (
      [
        Offset(left, top),
        Offset(right, top),
        Offset(left, bottom),
        Offset(right, bottom),
      ],
      {
        "left": left,
        "right": right,
        "top": top,
        "bottom": bottom,
      },
      Rect.fromLTWH(left, top, right - left, bottom - top)
    );
  }

  // 根据中心点和边长绘制正方形
  static void drawSquare(
      Canvas canvas, Offset center, double width, Paint paint) {
    canvas.drawRect(
      Rect.fromCenter(
        center: center,
        width: width,
        height: width,
      ),
      paint,
    );
  }

  /// 判断点是否在矩形内
  static bool isPointInRect(Offset point, Rect rect) {
    return rect.contains(point);
  }

  /// 判断点是否在多边形的外接矩形内
  static bool isPointInPolygon(Offset point, List<Offset> points) {
    final boundRect = PaintUtil.getBoundData(points);
    return PaintUtil.isPointInRect(point, boundRect.$3);
  }

  /// 绘制外接矩形
  static void drawBoundingRectAndControlPoint(
      Canvas canvas, List<Offset> points, Paint paint) {
    final controlPointPaint = Paint()
      ..color = const Color.fromARGB(255, 43, 26, 227)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;

    final boundRect = PaintUtil.getBoundData(points);
    canvas.drawRect(boundRect.$3, controlPointPaint);

    // 绘制控制点
    controlPointPaint.style = PaintingStyle.fill;
    const controlPointSize = 10.0;
    for (var point in boundRect.$1) {
      PaintUtil.drawSquare(canvas, point, controlPointSize, controlPointPaint);
    }
  }
}
